package com.formerlyknownasprince.wheresmystuff.models;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.DeserializationConfig;

import android.content.res.Resources;

import com.formerlyknownasprince.wheresmystuff.R;



/**
 * @author      Tim Swihart 		<email obscured since this file is public>
 * @version     0.3          
 * @since       2013-03-04
 */
public class LoginManager {
	private static final LoginManager loginManager = new LoginManager();
	
	public static LoginManager getInstance() {
		return loginManager;
	}
	
	private User user;
	private static String loginUrl;
	private static String registerUrl;
	private String error;
	private DefaultHttpClient http;
	private int failures = 0;
	
	private LoginManager() {
		// Using http so I can inspect traffic and verify that things are working.
		this.loginUrl = "http://128.61.104.203/login";
		this.registerUrl = "http://128.61.104.203/users/new";
		this.setUser(null);
		this.http = new DefaultHttpClient();
		ServerObject.setHttpClient(http);
		
	}
	
	/**
	 * @param email
	 * @param password
	 * @return true if the login was successful. False if unsuccessful, and the error message is set accordingly
	 * @throws IOException for possible network errors
	 */
	public boolean attemptLogin(String email, String password) throws IOException{
		if (failures >= 3) {
			this.setError("Too many failed login attempts");
			return false;
		}
		// connect to server, check credentials, take user if it works
		HttpPost loginPost = new HttpPost(loginUrl);

		List<NameValuePair> nvp = new ArrayList<NameValuePair>();
	    nvp.add(new BasicNameValuePair("email", email));
	    nvp.add(new BasicNameValuePair("password", password));
	    loginPost.setEntity(new UrlEncodedFormEntity(nvp));
	    
		HttpResponse response = http.execute(loginPost);
		
		InputStream is = response.getEntity().getContent();
		
		ObjectMapper mapper = new ObjectMapper();
		ServerObject.setObjectMapper(mapper);
		JSONMessage msg = new JSONMessage(mapper.readValue(is, JsonNode.class));
		if (msg.getErr().length() > 0 && msg.getErr() != "null") {
			this.setError(msg.getErr());
			return false;
		} else {
			this.setUser(new User(mapper, msg.getObj()));
			return true;
		}
	}
	
	/**
	 * 
	 * @param email
	 * @param password
	 * @return
	 * @throws IOException
	 */
	public boolean attemptRegister(String email, String password) throws IOException {
		if (failures >= 3) {
			this.setError("Too many failed login attempts");
			return false;
		}
		// connect to server, check credentials, take user if it works
		DefaultHttpClient hc = new DefaultHttpClient();
		this.http = hc; // the DefaultHttpClient handles our cookies for authentication. This needs to be passed around, or the cookies do
		HttpPost loginPost = new HttpPost(registerUrl);

		List<NameValuePair> nvp = new ArrayList<NameValuePair>();
	    nvp.add(new BasicNameValuePair("email", email));
	    nvp.add(new BasicNameValuePair("password", password));
	    loginPost.setEntity(new UrlEncodedFormEntity(nvp));
	    
		HttpResponse response = hc.execute(loginPost);
		
		InputStream is = response.getEntity().getContent();
		
		ObjectMapper mapper = new ObjectMapper();
		mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		JSONMessage msg = new JSONMessage(mapper.readValue(is, JsonNode.class));
		if (msg.getErr().length() > 0 && msg.getErr() != "null") {
			this.setError(msg.getErr());
			this.failures++;
			return false;
		} else {
			this.setUser(new User(mapper, msg.getObj()));
			return true;
		}
	}
	
	public User register(String email, String password) {
		return null;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String getError() {
		return error;
	}

	public void setError(String error) {
		this.error = error;
	}

	public DefaultHttpClient getHttpClient() {
		return http;
	}



}
